// 用于给docker容器写入hosts的东西
import request from '@/api/axiosRequest'
import { inspectContainerReq, startExec } from '@/api/docker'
import { isArray } from 'lodash-es'
import {
  Observable,
  Subscriber,
  forkJoin,
  lastValueFrom,
  mergeMap,
  of,
} from 'rxjs'

export interface HostExec {
  ip: string
  hostname: string
}

// 查询单个容器信息IP信息
const inspectOneContainer = (cid: string) => {
  return new Observable((subscriber: Subscriber<string>) => {
    inspectContainerReq(cid).then((res) => {
      subscriber.next(
        res.NetworkSettings?.Networks?.bridge?.IPAddress ?? '127.0.0.1'
      )
      subscriber.complete()
    })
  })
}

// 获取所有容器的IP地址
export const getContainersIPAddress = async (
  containerIds: string[],
  hostnames: string[]
) => {
  if (!isArray(containerIds) || containerIds.length <= 0) {
    throw new Error('容器的ID必填!')
  }
  // 容器的IP 地址
  const ipAddresses = await lastValueFrom(
    of(containerIds).pipe(
      mergeMap((x) => forkJoin(x.map((_x) => inspectOneContainer(_x))))
    )
  )

  let data: HostExec[] = []
  ipAddresses.forEach((v, i) => {
    data[i] = {
      ip: v,
      hostname: hostnames[i],
    }
  })
  return data
}

// 创建执行的命令
const createWriteHostExec = async (
  container_id: string,
  ipHosts: HostExec[]
) => {
  let scriptStr = ''

  ipHosts.forEach((v) => {
    scriptStr += `${v.ip} ${v.hostname}\n`
  })

  // 创建需要执行的命令
  return await request({
    url: `/containers/${container_id}/exec`,
    method: 'post',
    data: {
      AttachStdout: true,
      AttachStdin: true,
      Tty: false,
      Cmd: ['bash', '-c', `echo -e "${scriptStr}" >> /etc/hosts`],
      User: 'root',
    },
  })
}

//执行创建的脚本
export const runWriteHostsScript = async (
  containerIds: string[],
  hostnames: string[]
) => {
  const containerIPAddressData = await getContainersIPAddress(
    containerIds,
    hostnames
  ) //生成所有的ip和host对应关系

  for (let i = 0; i < containerIds.length; i++) {
    try {
      // 创建脚本命令
      const execId = await createWriteHostExec(
        containerIds[i],
        containerIPAddressData
      )
      //执行脚本
      const startExecLog = await startExec(execId.Id)
    } catch (e) {
      console.log(e)
    }
  }
}
